import React, {Component} from 'react';
import Block from '../../components/game/Block';
import Numbers from '../../../helpers/Numbers';

class Gobang extends Component {
    constructor(props) {
        super(props);
        this.html = [];
        this.array = [];
        this.i = 20;
        this.j = 20;
        this.weight = [0, 0, 0, 0, 0, 0, 0, 0];
        this.onClick = this.onClick.bind(this);
    }

    initialization() {
        for(let i = 0; i < this.i; i++) {
            const row = [];
            for(let j = 0; j < this.j; j++) {
                this.html.push(<Block key={`${i}-${j}`} ref={`${i}-${j}`} i={i} j={j} onClick={this.onClick}/>);
                row.push(0);
            }
            this.html.push(<br key={`br:${i}`}/>);
            this.array.push(row);
        }
        return this.html;
    }

    getRef(i, j) {
        return `${i}-${j}`;
    }

    onClick(i, j) {
        this.array[i][j] = -1;
        if (this.check(i, j)) {
            console.log('success');
            alert('success');
        } else {
            this.setWeight(i, j, 4);
            this.weight = [0, 0, 0, 0, 0, 0, 0, 0];
            this.AI();
        }
    }

    AI() {
        let list = [];
        let max = 0;
        for(let i = 0; i < this.i; i++) {
            for(let j = 0; j < this.j; j++) {
                if (this.array[i][j] >= max) {
                    max = this.array[i][j];
                    list.push({ i: i, j: j, val: this.array[i][j]});
                }
            }
        }
        list.sort((a, b) => { return b.val - a.val });
        let maxs = [];
        for (let obj of list) {
            if (obj.val >= max) {
                maxs.push(obj);
            }
        }

        const random = Numbers.random(0, maxs.length - 1);
        const ref = this.getRef(maxs[random].i, maxs[random].j);
        this.array[maxs[random].i][maxs[random].j] = -2;
        this.refs[ref].setClassName('bgc-red');
    }

    checkBorder(i, j) {
        return (i < this.i && i >= 0 && j < this.j && j >= 0);
    }

    setWeight(i, j, val) {
        const diff = 5 - val;
        this.setArray(i - diff, j, val, this.weight[0]);
        this.setArray(i - diff, j + diff, val, this.weight[1]);
        this.setArray(i, j + diff, val, this.weight[2]);
        this.setArray(i + diff, j + diff, val, this.weight[3]);
        this.setArray(i + diff, j, val, this.weight[4]);
        this.setArray(i + diff, j - diff, val, this.weight[5]);
        this.setArray(i, j - diff, val, this.weight[6]);
        this.setArray(i - diff, j - diff, val, this.weight[7]);
        if (val > 0) {
            --val;
            this.setWeight(i, j, val);
        }
    }

    setArray(i, j, val, weight) {
        if (this.checkBorder(i, j)) {
            const oldVal = this.array[i][j];
            if (oldVal === -1) {

            } else {
                this.array[i][j] += val + (weight ? weight : 0);
                const ref = this.getRef(i, j);
                this.refs[ref].setWeight(this.array[i][j]);
            }
        }
    }

    check(i, j) {
        return this.checkRow(i, j) || this.checkLine(i, j) || this.checkLeft(i, j) || this.checkRight(i, j);
    }

    checkRow(i, j) {
        let num = 1;
        for (let n = 1; n < 5; n++) {
            if (this.checkBorder(i, j + n) && this.array[i][j + n] === -1) {
                num++;
                this.weight[2] += 5 - n;
                this.weight[6] += 5 - n;
            }
            if (this.checkBorder(i, j - n) && this.array[i][j - n] === -1) {
                num++;
                this.weight[2] += 5 - n;
                this.weight[6] += 5 - n;
            }
        }
        return num === 5;
    }
    checkLine(i, j) {
        let num = 1;
        for (let n = 1; n < 5; n++) {
            if (this.checkBorder(i - n, j) && this.array[i - n][j] === -1) {
                num++;
                this.weight[0] += 5 - n;
                this.weight[4] += 5 - n;
            }
            if (this.checkBorder(i + n, j) && this.array[i + n][j] === -1) {
                num++;
                this.weight[0] += 5 - n;
                this.weight[4] += 5 - n;
            }
        }
        return num === 5;
    }
    checkLeft(i, j) {
        let num = 1;
        for (let n = 1; n < 5; n++) {
            if (this.checkBorder(i - n, j - n) && this.array[i - n][j - n] === -1) {
                num++;
                this.weight[3] += 5 - n;
                this.weight[7] += 5 - n;
            }
            if (this.checkBorder(i + n, j + n) && this.array[i + n][j + n] === -1) {
                num++;
                this.weight[3] += 5 - n;
                this.weight[7] += 5 - n;
            }
        }
        return num === 5;
    }
    checkRight(i, j) {
        let num = 1;
        for (let n = 1; n < 5; n++) {
            if (this.checkBorder(i - n, j + n) && this.array[i - n][j + n] === -1) {
                num++;
                this.weight[1] += 5 - n;
                this.weight[5] += 5 - n;
            }
            if (this.checkBorder(i + n, j + n) && this.array[i + n][j - n] === -1) {
                num++;
                this.weight[1] += 5 - n;
                this.weight[5] += 5 - n;
            }
        }
        return num === 5;
    }

    render() {
        return (
            <div className="gobang">
                {this.initialization()}
            </div>
        );
    }
}

export default Gobang;